package jumpingnotes.dao.hibernate;

import java.util.List;

import jumpingnotes.dao.ActivityDao;
import jumpingnotes.model.ActivityType;
import jumpingnotes.model.entity.Activity;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;

public class ActivityHibernateDao extends GenericHibernateDao<Activity> implements ActivityDao
{
	public ActivityHibernateDao()
	{
		super(Activity.class);
	}

	@SuppressWarnings("unchecked")
	public List<Activity> findActivityByMemberId(final int memberId, final int firstResult, final int maxResults)
	{
		return (List<Activity>) getHibernateTemplate().execute(new HibernateCallback()
		{
			public Object doInHibernate(Session session) throws HibernateException
			{
				Criteria criteria = session.createCriteria(Activity.class);

				criteria.createAlias("member", "member");
				criteria.add(Restrictions.eq("member.memberId", memberId));

				criteria.addOrder(Order.desc("createTime"));
				criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

				if (firstResult >= 0)
					criteria.setFirstResult(firstResult);
				if (maxResults > 0)
					criteria.setMaxResults(maxResults);

				return criteria.list();
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public List<Activity> findActivityByFriendMemberId(final int memberId, final int firstResult, final int maxResults)
	{
		return (List<Activity>) getHibernateTemplate().execute(new HibernateCallback()
		{
			public Object doInHibernate(Session session) throws HibernateException
			{
				Criteria criteria = session.createCriteria(Activity.class);
				criteria.createAlias("member", "member");

				Criteria friendCriteria = criteria.createCriteria("member.friendsForMemberIdTo");
				friendCriteria.createAlias("memberByMemberIdFrom", "memberByMemberIdFrom");
				friendCriteria.add(Restrictions.eq("memberByMemberIdFrom.memberId", memberId));

				criteria.addOrder(Order.desc("createTime"));
				criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

				if (firstResult >= 0)
					criteria.setFirstResult(firstResult);
				if (maxResults > 0)
					criteria.setMaxResults(maxResults);

				return criteria.list();
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public List<Activity> findActivityByGroupId(final int groupId, final int firstResult, final int maxResults)
	{
		return (List<Activity>) getHibernateTemplate().execute(new HibernateCallback()
		{
			public Object doInHibernate(Session session) throws HibernateException
			{
				Criteria criteria = session.createCriteria(Activity.class);
				criteria.createAlias("member", "member");

				Criteria groupMemberCriteria = criteria.createCriteria("member.groupMembers");
				groupMemberCriteria.createAlias("group", "group");
				groupMemberCriteria.add(Restrictions.eq("group.groupId", groupId));

				criteria.addOrder(Order.desc("createTime"));
				criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

				if (firstResult >= 0)
					criteria.setFirstResult(firstResult);
				if (maxResults > 0)
					criteria.setMaxResults(maxResults);

				return criteria.list();
			}
		});
	}

	@SuppressWarnings("unchecked")
	public List<Activity> findActivityByAllGroupMemberId(final int memberId, final int firstResult, final int maxResults)
	{
		return (List<Activity>) getHibernateTemplate().execute(new HibernateCallback()
		{
			public Object doInHibernate(Session session) throws HibernateException
			{
				Criteria criteria = session.createCriteria(Activity.class);
				criteria.createAlias("member", "member");

				Criteria groupMemberCriteria = criteria.createCriteria("member.groupMembers");
				groupMemberCriteria.createAlias("group", "group");

				Criteria groupMember2Criteria = criteria.createCriteria("group.groupMembers");
				groupMember2Criteria.createAlias("member", "member2");
				groupMember2Criteria.add(Restrictions.eq("member2.memberId", memberId));

				criteria.addOrder(Order.desc("createTime"));
				criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

				if (firstResult >= 0)
					criteria.setFirstResult(firstResult);
				if (maxResults > 0)
					criteria.setMaxResults(maxResults);

				return criteria.list();
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public List<Activity> findActivityPlaying(final int firstResult, final int maxResults)
	{
		return (List<Activity>) getHibernateTemplate().execute(new HibernateCallback()
		{
			public Object doInHibernate(Session session) throws HibernateException
			{
				Criteria criteria = session.createCriteria(Activity.class);

				criteria.createAlias("activityTemplate", "activityTemplate");
				criteria.add(Restrictions.eq("activityTemplate.type", ActivityType.DEPLOY_PLAY));

				criteria.addOrder(Order.desc("createTime"));
				criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

				if (firstResult >= 0)
					criteria.setFirstResult(firstResult);
				if (maxResults > 0)
					criteria.setMaxResults(maxResults);

				return criteria.list();
			}
		});
	}

	@SuppressWarnings("unchecked")
	public List<Activity> findActivityRecording(final int firstResult, final int maxResults)
	{
		return (List<Activity>) getHibernateTemplate().execute(new HibernateCallback()
		{
			public Object doInHibernate(Session session) throws HibernateException
			{
				Criteria criteria = session.createCriteria(Activity.class);

				criteria.createAlias("activityTemplate", "activityTemplate");
				criteria.add(Restrictions.eq("activityTemplate.type", ActivityType.AUDIO_RECORD));

				criteria.addOrder(Order.desc("createTime"));
				criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

				if (firstResult >= 0)
					criteria.setFirstResult(firstResult);
				if (maxResults > 0)
					criteria.setMaxResults(maxResults);

				return criteria.list();
			}
		});
	}
}
